/**
 * number utils
 * Copyright (c) 2009 cmiscm.com
 * date of final modification : 2008. 01. 29
*/
package  com.cmiscm.utils.common
{
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	/**
	 * Number Utilities.
     * 
     */
	public class NumberUtilities 
	{		
		/**
		 * Approximate value 2 radical root
		 * <p>
		 * 근사치의 2의 거듭제곱근으로 변환 
		 * @param $data Number
		 * @param $target Target
		 * @return 
		 * 
		 */			
		public static function re2($data:int, $target:int=2):int
		{
			if ($data == 0) return 0;
			else if (abs($data) > $target) return re2($data, $target * $target);
			else return $target;
		}
		
		/**
		 * In case $cur is changed from $top to $bottom, return change value from $min to $max
		 * <p>
		 * $cur가 $top부터 $bottom까지 변할때 $min부터 $max까지 변한 값을 리턴
		 * @param $cur Current value
		 * @param $top Top
		 * @param $bottom Bottom
		 * @param $min Minimum
		 * @param $max Maximum
		 * @return 
		 * 
		 */		   	
		public static function getCurrent($cur:Number, $top:Number, $bottom:Number, $min:Number, $max:Number):Number 
		{
			return ($max - $min) / ($bottom - $top) * ($cur - $top) + $min;
		}
	
		/**
		 * Fiexed size
		 * <p>
		 * 이미지 사이즈를 정해진 값에 맞춤
		 * @param $mcW MC width
		 * @param $mcH MC height
		 * @param $stW Stage width
		 * @param $stH Stage height
		 * @param $full true in case cutting image
		 * @return 
		 * 
		 */		
		public static function setFiexedImg($mcW:Number, $mcH:Number, $stW:int, $stH:int, $full:Boolean=false):Rectangle
		{
			var sH:int;
			var sW:int;
			var sPer:Number = $stW / $stH;
			var imgPer:Number = $mcW / $mcH;
			var imgX:int = 0;
			var imgY:int = 0;
			
			if ($full) {
				if (imgPer > sPer) {
					sW = Math.round($mcW * ($stH / $mcH));
					sH = $stH;
					imgX = Math.round(($stW - sW) >> 1);
					imgY = 0;
				} else {
					sW = $stW;
					sH = Math.round($mcH * ($stW / $mcW));			
					imgX = 0;
					imgY = Math.round(($stH - sH) >> 1);
				}
			} else {
				if (imgPer < sPer) {
					sW = Math.round($mcW * ($stH / $mcH));
					sH = $stH;
					imgX = Math.round(($stW - sW) >> 1);
					imgY = 0;
				} else {
					sW = $stW;
					sH = Math.round($mcH * ($stW / $mcW));			
					imgX = 0;
					imgY = Math.round(($stH - sH) >> 1);
				}
			}
			return new Rectangle(imgX, imgY, sW, sH);
		}
		
		/**
		 * Return wall position 
		 * @param $index Index number
		 * @param $x_num X number
		 * @param $x_gap X gap
		 * @param $y_gap Y gap
		 * @return 
		 * 
		 */		
		public static function getWallPosition($index:int, $x_num:int, $x_gap:int, $y_gap:int):Point
		{
			var tx:int = ($index % $x_num) * $x_gap;
			var ty:int = int($index / $x_num) * $y_gap;
			return new Point(tx, ty);
		}
		
		/**
		 * Add zero 
		 * @param $num Number
		 * @param $no Zero number
		 * @return 
		 * 
		 */			
		public static function addZeros($num:int, $no:int=1):String
		{
			var str:String = String($num);			
			var zero:String = "";
			var len:int = str.length;
			var total:int = $no + 1;
			var i:int;
			if (len < total) {				
				var zeroTotal:int = total - len;				
				for (i=1; i<=zeroTotal; i++) zero += "0";
				str = zero + str;			
			}			
			return str;
		}
		
		
		/**
		 * Add dot 
		 * @param $num Number
		 * @param $dot Dot string
		 * @return 
		 * 
		 */		
		public static function addDots($num:int, $dot:String=","):String
		{
			if (isNaN($num)) return "-"; 			
			var arr:Array = String($num).split(""); 
			var tlen:int = arr.length; 
			var clen:int = Math.ceil(tlen / 3); 
			var i:int;
			for (i=1; i<clen; i++) arr.splice(tlen - i * 3, 0, $dot); 
			return arr.join(""); 
		}
			
		/**
		 * Fast speed abs function 
		 * @param value Number
		 * @return 
		 * 
		 */		
		public static function abs($value:Number):Number
		{
			return $value < 0 ? -$value : $value;
		}
		
	    /**
	     * Round 
	     * @param $nNumber Number
	     * @param $nRoundToInterval Interval
	     * @return 
	     * 
	     */		
	    public static function round($nNumber:Number, $nRoundToInterval:Number=1):Number 
	    {
	      return Math.round($nNumber / $nRoundToInterval) * $nRoundToInterval;
	    }
		
	    /**
	     * Floor 
	     * @param $nNumber Number
	     * @param $nRoundToInterval Interval
	     * @return 
	     * 
	     */		
	    public static function floor($nNumber:Number, $nRoundToInterval:Number=1):Number 
	    {
	      return Math.floor($nNumber / $nRoundToInterval) * $nRoundToInterval;
	    }
		
	    /**
	     * Ceil 
	     * @param $nNumber Number
	     * @param $nRoundToInterval Interval
	     * @return 
	     * 
	     */		
	    public static function ceil($nNumber:Number, $nRoundToInterval:Number=1):Number 
	    {
	      return Math.ceil($nNumber / $nRoundToInterval) * $nRoundToInterval;
	    }
	    
	    /**
	     * Random 
	     * @param $nMinimum Minimum
	     * @param $nMaximum Maximum
	     * @param $nRoundToInterval Interval
	     * @return 
	     * 
	     */	    
	    public static function random($nMinimum:Number, $nMaximum:Number=0, $nRoundToInterval:Number=1):Number 
	    {
			if($nMinimum > $nMaximum) {
				var nTemp:Number = $nMinimum;
				$nMinimum = $nMaximum;
				$nMaximum = nTemp;
			}
	        var nDeltaRange:Number = ($nMaximum - $nMinimum) + (1 * $nRoundToInterval);	
	        var nRandomNumber:Number = Math.random() * nDeltaRange;	
	        nRandomNumber += $nMinimum;	
	        return floor(nRandomNumber, $nRoundToInterval);
		}


	}
}